package com.googlecode.imule.data;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

/**
 * A parser to clean the XML to "meaningful" elements for the components.
 * 
 * @author Neil Cowzer, Owen Phelan
 */
public class Parse {

	public static Component component(String XML) throws IOException, SAXException{
		Digester digester = new Digester();
		digester.setValidating( false );
		
		digester.addObjectCreate("component", Component.class);	// push a new component to the stack
		
		// add the 'fields'
		digester.addBeanPropertySetter("component/type", "type");	// add the type
		digester.addBeanPropertySetter("component/description", "description");
		digester.addBeanPropertySetter("component/protocol", "protocol");
		
		// add the methods
		digester.addObjectCreate("component/methods/method", Method.class);	// push a new Method
		digester.addBeanPropertySetter("component/methods/method/name", "name");
		digester.addBeanPropertySetter("component/methods/method/type", "type");	
		//add the arguments class
		digester.addObjectCreate("component/methods/arguments", Argument.class);
		
		// add the fields from arguments
		digester.addBeanPropertySetter("components/methods/arguements/arguement/type", "type");
		digester.addBeanPropertySetter("components/methods/arguements/arguement/value", "value");
		
		//pop the fields
		digester.addSetNext("components/methods/arguments/arguement", "addArgument");
		
		digester.addSetNext("component/methods/method", "addMethod");	/* add the method once we hit the closing tag
																		 * this adds the method we created above to the Component 
																		 */
		return /*null*/(Component) digester.parse(convertString(XML));
	}	
	public static Component component(File file) throws IOException, SAXException{
		Digester digester = new Digester();
		digester.setValidating( false );
		
		digester.addObjectCreate("component", Component.class);	// push a new component to the stack
		
		// add the 'fields'
		digester.addBeanPropertySetter("component/type", "type");	// add the type
		digester.addBeanPropertySetter("component/description", "description");
		digester.addBeanPropertySetter("component/protocol", "protocol");
		
		// add the methods
		digester.addObjectCreate("component/methods/method", Method.class);	// push a new Method
		digester.addBeanPropertySetter("component/methods/method/name", "name");
		digester.addBeanPropertySetter("component/methods/method/type", "type");	
		
		//add the arguments class
		digester.addObjectCreate("component/methods/arguments", Argument.class);
		
		// add the fields from arguments
		digester.addBeanPropertySetter("components/methods/arguements/arguement/type", "type");
		digester.addBeanPropertySetter("components/methods/arguements/arguement/value", "value");
		
		//pop the fields
		digester.addSetNext("components/methods/arguments/arguement", "addArgument");
		
		digester.addSetNext("component/methods/method", "addMethod");	/* add the method once we hit the closing tag
																		 * this adds the method we created above to the Component 
																		 */
		
		return /*null*/(Component) digester.parse(file);
	}
	

	public static Action action(String xml) throws IOException, SAXException{
		Digester digester = new Digester();
		digester.setValidating( false );

		digester.addObjectCreate("action", Action.class);	// push a new component to the stack
		digester.addSetProperties("action", "id", "id");
		
		// add the 'fields'
		digester.addBeanPropertySetter("action/method/name", "name");	// add the type
		digester.addBeanPropertySetter("action/method/type", "type");
		
		// add the methods
		digester.addObjectCreate("action/method/arguments/argument", Argument.class);	// push a new Method
		digester.addBeanPropertySetter("action/method/arguments/argument/type", "type");
		digester.addBeanPropertySetter("action/method/arguments/argument/value", "value");	
		
		//pop the fields
		digester.addSetNext("action/method/arguments/argument", "addArgument");
	
		return /*null*/(Action) digester.parse(convertString(xml));
	}
	
	//generate XML string for message passing
	public static String Action(String serviceName, String method, String type, String value){

		String xml = "";
		xml += ("<action id =\"" + serviceName + "\">\n");
		xml += ("	<method>\n");
		xml += ("		<name>"+ method + "</name>");
		xml += ("		<type> void </type>\n");
		xml += ("		<arguments>\n");
		xml += ("			<argument><type>" +	type + "</type><value>" + value + "</value></argument>");
		xml += ("		</arguments>\n");
		xml += ("	</method>\n");
		xml += ("</action>\n");
		return xml;
	}
	
	// Will be used in proper program as it allow us to read it as a string
	private static InputStream convertString(String XML){
		byte[] byteArray = XML.getBytes();
		return new ByteArrayInputStream(byteArray);
	}
	
	
	public static void main(String[] args) throws IOException, SAXException {
		Component x = Parse.component("resources/component.xml");
		System.out.println(x);
		
	}
}
